#!/bin/bash
# ------------------------------------------------------------------------------
#
# SERPRO - Serviço Federal de Processamento de Dados - Regional Brasília
# Superintendência: SUPCD/CDBSA/CDSSB
#
# Nome do programa: padronizaEtcHosts.sh
#
# Site:
#
# Descrição abreviada de funcionalidade: Organiza um arquivo /etc/hosts,
# alinhando as colunas correspondentes aos nomes dos hosts de acordo com os
# tamanhos de cada uma delas.
#
# Autor(es): Moacir da Cruz Souza Filho <moacir.souza-filho@serpro.gov.br>
#
# Data de criação do programa: 07/07/2011
#
# ------------------------------------------------------------------------------
#
# Descrição detalhada de funcionalidade:
#
# Exemplo(s) de uso:
# $ executa
#
# ------------------------------------------------------------------------------
#
# Lista de Modificações
#
# Autor: Moacir da Cruz Souza Filho <moacir.souza-filho@serpro.gov.br>
#
# Versão 0.1 - 07/07/2011:
# - Testes preliminares com estruturas de laços e filtragem de padrões.
# - Criação da função "colunas" que possui um grep capaz de filtrar linhas
# que possuem endereços IP.
# - Alteração da função "colunas" para que ela criasse arquivos temporários
# numerados de 1 a n, representando todas as eventuais colunas existentes
# em um arquivo /etc/hosts (IP's e nomes de hosts).
# - Primeiros testes de alinhamento utilizando um misto das funcionalidades
# dos comandos printf e paste.
#
# Versão 0.2 - 15/07/2011:
# - Criação de uma estrutura de laço (while) capaz de controlar a quantidade
# de vezes que a função "colunas" é chamada para criar os arquivos temporários
# com os dados do arquivo /etc/hosts.
# - Melhorias na função "colunas". Dois tr foram acrescidos para se
# encarregar da limpeza do arquivo /etc/hosts (i.e., transformação de tabs
# em espaços e redução de múltiplos espaços a espaços singulares). Por fim
# foi adicionado um sed capaz de remover linhas vazias de cada arquivo que
# continha as colunas do /etc/hosts, criando um arquivo temporário (tmp) para
# auxiliar na parada do laço.
# - Correção de bugs relacionados à maneira como o printf foi utilizado
# inicialmente. Foi necessário perceber que, para que o alinhamento
# funcionasse corretamente, era preciso sempre ter ao menos um caractere por
# linha, nunca uma linha vazia.
#
# Versão 0.3 - 17/07/2011:
# - Organização da função "colunas", para que os comandos dela não
# ultrapassassem o limite de 80 colunas imposto por esse cabeçalho.
# - Reorganização do cabeçalho, preenchimento de informações detalhadas e
# criação das seções "Funções auxiliares" e "Processamento".
# - Criação das chamadas externas a algumas funções auxiliares fora do laço
# principal do processamento: em alguns casos é preciso fazer ajustes que não
# podem passar pelo laço.
#
# Versão 0.4 - 18/07/2011:
# - Criação dos procedimentos de backup do arquivo /etc/hosts afim de evitar
# que, em casos de múltiplas execuções desse programa em um mesmo dia, não se
# perca o arquivo original.
# - O tr usado na função maiorLinha para transformar todos os caracteres
# imprimíveis em um ponto precisou ser trocado por um sed, pois em algumas
# máquinas AIX a flag complemento do tr (-c) não funciona da mesma forma que
# em máquinas linux.
#
# Agradecimentos:
#
# Licença: GPL
#
# ------------------------------------------------------------------------------

# -------------------------[ Definição de variáveis ]---------------------------

DATA_EXECUCAO=$(date "+%T_%d-%m-%Y")
HOSTS_TEMPORARIO="hosts.$DATA_EXECUCAO"
POSICOES_COMENTARIOS="${HOSTS_TEMPORARIO}_posicao"

### Cópia de seguranca do arquivo /etc/hosts
cp /etc/hosts $HOSTS_TEMPORARIO

# ---------------------------[ Funções auxiliares ]-----------------------------

### A função colunas separa cada coluna do /etc/hosts em um arquivo numerado,
### além de criar dois arquivos temporários que servem de auxílio para o
### alinhamento final das informações

function colunas(){
egrep -E "^([0-9]{1,3}.){3}[0-9]{1,3}|:" $HOSTS_TEMPORARIO |
tr "\t" " " |
tr -s " " |
cut -d " " -f $1 > $1

sed '/^$/d' $1 > tmp
sed 's/^$/@/' $1 > tmp2
}

### Retorna o inteiro que indica a linha mais comprida (que contem mais
### caracteres imprimíveis) de um arquivo

function maiorLinha(){
sed "s/././g" "$1" |
sort |
tail -n 1 |
tr -d "\n" |
wc -c
}

### Coletando todos os comentários e as respectivas linhas em que se encontram
### no arquivo
function preservaComentarios(){
grep -n "^[^[:digit:]]" "$1" > "$POSICOES_COMENTARIOS"
#grep -n "^#" "$1" > "$POSICOES_COMENTARIOS"
}

### Reinsere os comentários depois do processamento principal de organização
### das colunas do /etc/hosts
function reinsereComentarios(){
while read linha
do
a=$(echo "$linha" | cut -d ":" -f 1)
b=$(echo "$linha" | cut -d ":" -f 2-)

#echo "POS: ${a}"
#echo "LINHA: ${b}"
sed -i "${a} a \
${b}" FINAL
done < "$POSICOES_COMENTARIOS"
}

# -----------------------------[ Processamento ]--------------------------------

j=1
colunas $j
tamanhoColunas="$(maiorLinha $j)"
quantidadeColunas="$j"

preservaComentarios "$HOSTS_TEMPORARIO"

while [ -s tmp ]
do
mv tmp2 $j
j=$((j+1))
colunas $j
tamanhoColunas="$tamanhoColunas $(maiorLinha $j)"
quantidadeColunas="$quantidadeColunas $j"
done

sed 's/^$/@/' $j > tmp2
mv tmp2 $j

function ajusta(){
params=""

while [ -n "$1" ]
do
params="${params}%-${1}s "
shift
done

printf "${params}\n" $(paste $quantidadeColunas) | sed 's/@/ /g' > FINAL
echo printf "${params}\n" $(paste $quantidadeColunas) | sed 's/@/ /g' > FINAL
sed -i 's/ *$//g' FINAL
}

ajusta $tamanhoColunas

reinsereComentarios
